Skip to content

FE-537: Observer agent + entity persistence#23

Merged
lunelson merged 2 commits into
mainfrom
ln/fe-537-observer-agent
Apr 7, 2026
Merged

FE-537: Observer agent + entity persistence#23
lunelson merged 2 commits into
mainfrom
ln/fe-537-observer-agent

Conversation

@lunelson
Copy link
Copy Markdown
Contributor

@lunelson lunelson commented Apr 2, 2026

feat: agent pattern + observer entity persistence (FE-537)

Refactors conductTurn into generator composition (D27): interviewer
and observer agents are async generators composed via yield*.
Shared SDK stream translator in sdk.ts. Observer uses outputFormat
for structured JSON extraction (D28). ResultMessage inspection
provides per-agent metrics (D29). Observer errors are non-fatal.

New: sdk.ts, observer.ts; 147 tests (24 new), all pass.

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

traceability: slice 5 done — D27/D28/D29, A24/A25 added, I20/I21/I22 established

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

@linear
Copy link
Copy Markdown

linear Bot commented Apr 2, 2026

FE-537 Observer agent + entity persistence

After each exchange, fire separate queryStructured call to extract entities. Materialize into decision, assumption, requirement, scope, goal tables. Emit data-entities SSE event.

Copy link
Copy Markdown
Contributor Author

lunelson commented Apr 2, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@lunelson lunelson changed the base branch from ln/fe-558-ui-foundation to graphite-base/23 April 2, 2026 18:59
lunelson and others added 2 commits April 3, 2026 10:26
Refactors conductTurn into generator composition (D27): interviewer
and observer agents are async generators composed via yield*.
Shared SDK stream translator in sdk.ts. Observer uses outputFormat
for structured JSON extraction (D28). ResultMessage inspection
provides per-agent metrics (D29). Observer errors are non-fatal.

New: sdk.ts, observer.ts; 147 tests (24 new), all pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…established

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@lunelson lunelson force-pushed the ln/fe-537-observer-agent branch from 135f857 to 8d6848a Compare April 3, 2026 18:23
@lunelson lunelson changed the base branch from graphite-base/23 to main April 3, 2026 18:23
@lunelson lunelson changed the title feat: agent pattern + observer entity persistence (FE-537) FE-537: Observer agent + entity persistence Apr 7, 2026
@lunelson lunelson marked this pull request as ready for review April 7, 2026 15:30
@augmentcode
Copy link
Copy Markdown

augmentcode Bot commented Apr 7, 2026

🤖 Augment PR Summary

Summary: Adds an “observer” agent that runs after each interview turn to extract/persist decisions & assumptions, and refactors the agent pipeline into composable async generators.

Changes:

  • Refactored conductTurn() into a thin sequencer composing runInterviewer() and runObserver()
  • Introduced sdk.ts with shared SDK stream_eventDomainEvent translation and ResultMessage-based metrics (agent-metrics)
  • Added observer.ts using SDK outputFormat structured JSON to extract entities and write them to SQLite
  • Added DB helpers for decision/assumption creation, turn linkage, and dependency-edge insertion
  • Updated observer context rendering to use md-pen tables/headings
  • Extended SSE adapter to emit data-observer-result; moved finish termination to the Express route so it occurs after observer events
  • Added/updated unit tests covering observer persistence, stream translation, SSE translation, and metrics extraction

🤖 Was this summary useful? React with 👍 or 👎

Copy link
Copy Markdown

@augmentcode augmentcode Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 3 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread src/server/observer.ts
// Parse structured output
const parsed = observerOutputSchema.parse(resultMessage.structured_output);

// Persist entities in a transaction-like sequence
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/server/observer.ts:L133: This persistence path isn’t actually wrapped in a DB transaction, so a late FK/PK failure (e.g., bad/duplicate parent IDs) can leave partially-created entities/edges while conductTurn() only reports observer-error. That can make the entity graph inconsistent across turns.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Comment thread src/server/observer.ts
type: 'object',
properties: {
content: { type: 'string' },
rationale: { type: 'string', nullable: true },
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/server/observer.ts:L93: The outputFormat schema uses nullable: true, which isn’t valid draft-07 JSON Schema (commonly type: ['string','null']) and the Agent SDK docs call for “standard JSON Schema”. If the SDK validates strictly, observer extraction can fail even with otherwise-correct model output.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Comment thread src/server/sdk.ts
return [
{
type: 'tool-call-delta',
toolCallId: toolBlock?.toolCallId ?? '',
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/server/sdk.ts:L76: When an input_json_delta arrives without a tracked tool_use block, this emits toolCallId: '', which downstream (SSE + assembleAssistantParts()) can’t associate with a real tool call. If this occurs due to out-of-order/unexpected SDK events, tool-call args may be silently dropped or misattributed.

Severity: low

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Copy link
Copy Markdown
Contributor Author

lunelson commented Apr 7, 2026

Merge activity

  • Apr 7, 4:18 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Apr 7, 4:18 PM UTC: @lunelson merged this pull request with Graphite.

@lunelson lunelson merged commit d1d6d55 into main Apr 7, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant